package com.zaozhuang.robot;

import android.app.AlertDialog;
import android.content.ActivityNotFoundException;
import android.content.ComponentName;
import android.content.Context;
import android.content.DialogInterface;
import android.content.Intent;
import android.content.ServiceConnection;
import android.graphics.Color;
import android.icu.text.Transliterator;
import android.net.Uri;
import android.os.Build;
import android.os.Bundle;
import android.os.Handler;
import android.os.IBinder;
import android.os.Looper;
import android.os.RemoteException;
import android.text.Spannable;
import android.text.SpannableString;
import android.text.style.ForegroundColorSpan;
import android.util.Log;
import android.view.Gravity;
import android.view.LayoutInflater;
import android.view.View;
import android.widget.Button;
import android.widget.ImageView;
import android.widget.ScrollView;
import android.widget.TextView;
import android.widget.Toast;

import androidx.appcompat.app.AppCompatActivity;
import androidx.recyclerview.widget.LinearLayoutManager;
import androidx.recyclerview.widget.RecyclerView;

import com.airbnb.lottie.LottieAnimationView;
import com.google.android.material.textfield.TextInputEditText;
import com.google.gson.Gson;
import com.helang.lib.IMyAidlCallBackInterface;
import com.helang.lib.IMyAidlInterface;
import com.journeyapps.barcodescanner.BarcodeResult;
import com.journeyapps.barcodescanner.DecoratedBarcodeView;
import com.zaozhuang.robot.request.EmploymentInfo;
import com.zaozhuang.robot.request.PersonCheckQRCodeRequestBean;
import com.zaozhuang.robot.request.PersonCheckQRCodeResponseBean;
import com.zaozhuang.robot.request.SBRequestBean;
import com.zaozhuang.robot.request.SBResponseBean;
import com.zaozhuang.robot.schedulerequest.PeriodicRequestTask;
import com.zaozhuang.robot.utils.CustomCaptureManager;
import com.zaozhuang.robot.utils.ImageDownloader;
import com.zaozhuang.robot.websocket.Constants;
import com.zaozhuang.robot.websocket.SendMessageEntity;
import com.zaozhuang.robot.websocket.ServiceUtils;
import com.zaozhuang.robot.websocket.SocketJobListEntity;
import com.zaozhuang.robot.websocket.SocketMessageEndEntity;
import com.zaozhuang.robot.websocket.SocketMessageEntity;
import com.zaozhuang.robot.websocket.socketService;

import org.greenrobot.eventbus.EventBus;
import org.greenrobot.eventbus.Subscribe;
import org.greenrobot.eventbus.ThreadMode;

import java.io.IOException;
import java.text.SimpleDateFormat;
import java.util.ArrayList;
import java.util.Date;
import java.util.HashMap;
import java.util.List;
import java.util.Locale;
import java.util.Map;

import okhttp3.Call;
import okhttp3.Callback;
import okhttp3.MediaType;
import okhttp3.OkHttpClient;
import okhttp3.Request;
import okhttp3.RequestBody;
import okhttp3.Response;

/*
语音通话逻辑：
onCreate里wakeup,然后startRecord开始接收。接收到后触发callback，stopRecord，callback的msg展示在recyclerview。
msg用websocket的sendMsg给到后台，后台返回response。response展示在recyclerview。然后startRecord。
以此循环。
问题点：
1.模拟打字效果如何设计。假设人0s的时候说话，3s的时候说完。 3s的时候callback才触发，这时候是直接显示还是模拟打字？其实已经是滞后了，真想模拟打字应该是
接收一个字就callback一个字。  看了下豆包，也是3s的时候触发callback。然后一瞬间展示所有人的文本。
这说明人这块不需要模拟打字。仅机器人回答的时候模拟打字即可。合理
 */
public class TalkActivity extends AppCompatActivity implements socketService.MessageListener, CustomCaptureManager.OnBarcodeResultListener {
    private TextView mSimulateAskBtn;
    private TextView mResetProcessBtn;
    private IMyAidlInterface iMyAidlInterface;
    private ServiceCallBack serviceCallBack;
    private MyServiceConnection myServiceConnection;
    //    private Handler handler = new Handler();
    private String welComeStr = "欢迎使用枣庄人社局智能机器人";
    // 初始化对话数据
    private ChatAdapter adapter;
    private int currentStep = 0;
    private final Handler handler = new Handler(Looper.getMainLooper());
    RecyclerView recyclerView;
    private TextView tvTime, tvDate, tvType;
    private TextView mStopOutputBtn;
    private TextView mPauseResumeBtn;
    private TextView mDestoryBtn;
    private TextView logText;
    private ScrollView logContainer;
    private SimpleDateFormat timeFormat = new SimpleDateFormat("HH:mm", Locale.getDefault());
    private SimpleDateFormat dateFormat = new SimpleDateFormat("yyyy-MM-dd", Locale.getDefault());

    private int mTalkingState = 0;

    private static final int IDLE = 0;//闲置中，人和机器人都没说话
    private static final int MEN_TALKING = 1;//人在说话中
    private static final int ROBOT_THINKING = 2;//机器人请求大模型中
    private static final int ROBOT_ANSWERING = 3;//机器人回答中
    private TextView mTalkingStateText;
    private LottieAnimationView mWaveAnim;

    private socketService.LocalBinder mServiceBinder;
    private boolean mBound = false;
    String uuid = "";
    ArrayList<String> targetPinyins = new ArrayList<>();
    private boolean isForeground = false;
    //对话框相关 ---begin
    private CustomCaptureManager capture;
    private DecoratedBarcodeView qrCodePreview;
    private TextView remindTv;
    private ImageView qrCodeImg;
    private View phoneInputContainer;
    private PeriodicRequestTask periodicRequestTask;
    private ImageView closeDialogBtn;
    private Button submitBtn;
    private TextInputEditText phoneInput;
    private Map<String, String> submitInfo = new HashMap<>();
    private TextView step1;
    private TextView step2;
    private TextView step3;
    //对话框相关 ---end
    private App app;

    private String lastTTs = "";
    private String job_posted = "已发布";
    private String job_deliverd = "已投递，3到5个工作日会有人联系您";
    private ServiceConnection mServiceConnection = new ServiceConnection() {
        @Override
        public void onServiceConnected(ComponentName name, IBinder service) {
            mServiceBinder = (socketService.LocalBinder) service;
            socketService socketServiceInstance = mServiceBinder.getService();
            mBound = true;
            socketServiceInstance.setMessageListener(TalkActivity.this); // 注册监听
            // 发送消息示例
//            if (socketServiceInstance != null) {
//                socketServiceInstance.sendMessage("测试消息");
//            }
        }

        @Override
        public void onServiceDisconnected(ComponentName name) {
            mBound = false;
            mServiceBinder = null;
        }
    };

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_chat);
        bindService();
        initView();
        initData();
        updateTime();
        startRealtimeUpdates();
        setTalkingState(IDLE);
        //TODO 打开
        wakeUpMic();

        initWebSocket();
        EventBus.getDefault().register(this);
    }

    private static final String HOST = "120.220.83.9:8333";

    private void initWebSocket() {
        String url = "ws://" + HOST + "/agent/chat/";
//        Log.e("TalkActivity uuid initWebSocket", uuid);
        String token = "";
        ServiceUtils.startWebSocketService(this, token, url);

        // 绑定服务
        bindWebSocketService();
    }

    private void initData() {
        targetPinyins.add("jiesuhuihua");
        targetPinyins.add("jieshuhuihua");
        targetPinyins.add("jiesuduihua");
        targetPinyins.add("jieshuduihua");
        targetPinyins.add("guanbihuihua");
        targetPinyins.add("guanbiduihua");
        targetPinyins.add("fanhuishouye");
    }

    private void bindWebSocketService() {
        Intent intent = new Intent(this, socketService.class);
        bindService(intent, mServiceConnection, Context.BIND_AUTO_CREATE);
    }

    private void unbindWebSocketService() {
        if (mBound) {
            unbindService(mServiceConnection);
            mBound = false;
            mServiceBinder = null;
        }
    }
    private void wakeUp(){
        if (iMyAidlInterface != null) {
            try {
                /**
                 *  direct 为波束方位 以4麦阵列为例，取值0,1,2, 0为麦克风的第一与第二麦头之间波速,1为中间波速，2为三和四麦头的波速
                 */
                String direct = "1";
                iMyAidlInterface.sendMessage("wakeup", direct);
            } catch (RemoteException e) {
                e.printStackTrace();
            }
        }
    }
    private void wakeUpMic() {
//        wake up
        Log.e("wakeUpMic", iMyAidlInterface != null ? "true" : "false");
        //post runnable到消息队列尾部，因为不这样bindService还没结束
        handler.postDelayed(new Runnable() {
            @Override
            public void run() {
                Log.e("wakeUpMic", iMyAidlInterface != null ? "true" : "false");
                if (app.useDeviceWakeup) {
                    startTTs(welComeStr);
                } else {
                    if (iMyAidlInterface != null) {
                        try {
                            /**
                             *  direct 为波束方位 以4麦阵列为例，取值0,1,2, 0为麦克风的第一与第二麦头之间波速,1为中间波速，2为三和四麦头的波速
                             */
                            String direct = "1";
                            iMyAidlInterface.sendMessage("wakeup", direct);
                        } catch (RemoteException e) {
                            e.printStackTrace();
                        }
                    }
                }
            }
        }, 0);
    }

    private void startRecord() {
        setTalkingState(MEN_TALKING);
        if (iMyAidlInterface != null) {
            try {
                iMyAidlInterface.sendMessage("startrecord", "");
            } catch (RemoteException e) {
                e.printStackTrace();
            }
        }
    }

    private void stopRecord() {
        if (iMyAidlInterface != null) {
            try {
                iMyAidlInterface.sendMessage("stoprecord", "");
            } catch (RemoteException e) {
                e.printStackTrace();
            }
        }
    }


    private int questionIndex = 0;

    private int noVoiceInputTimes = 0;//用来控制自动退出当前页面
    private int MAX_SILENT_TIME = 4;

    private void initView() {
        recyclerView = findViewById(R.id.recyclerView);
        LinearLayoutManager layoutManager = new LinearLayoutManager(this);
        layoutManager.setStackFromEnd(true);
        recyclerView.setLayoutManager(layoutManager);
        adapter = new ChatAdapter(new ArrayList<>());
        recyclerView.setAdapter(adapter);
        //很重要，解决模拟打字的闪烁问题
        recyclerView.setItemAnimator(null);
        tvTime = findViewById(R.id.tv_time);
        tvDate = findViewById(R.id.tv_date);
        tvType = findViewById(R.id.center_text);
        logText = (TextView) findViewById(R.id.logs);
        logContainer = (ScrollView) findViewById(R.id.logs_container);
//        logText.setMovementMethod(ScrollingMovementMethod.getInstance());
        app = (App) getApplication();
        logContainer.setVisibility(app.isDebugMode ? View.VISIBLE : View.GONE);
        logText.setVisibility(app.isDebugMode ? View.VISIBLE : View.GONE);
        mTalkingStateText = (TextView) findViewById(R.id.talking_stata_text);
        mWaveAnim = (LottieAnimationView) findViewById(R.id.wave_anim);
        mStopOutputBtn = findViewById(R.id.stop_output_btn);
        mStopOutputBtn.setVisibility(View.INVISIBLE);
        mDestoryBtn = findViewById(R.id.destory_btn);
        mSimulateAskBtn = findViewById(R.id.simulate_ask_btn);
        mSimulateAskBtn.setVisibility(app.isDebugMode ? View.VISIBLE : View.GONE);
        mResetProcessBtn = findViewById(R.id.reset_process_btn);
        mStopOutputBtn.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                // 停止当前回答
                sendMessage(Constants.SendMessageType.TYPE_STOP, "");
            }
        });

//        String[] questionArr = {"你好", "你能做什么", "你只会做这些吗", "你真笨啊", "你能不能聪明点", "你能不能快点", "你能不能慢点", "你能不能说的好听点", "你能不能说的简单点", "你能不能说的详细点"};
//        String[] questionArr = {"求职", "游泳教练", "两千", "本科", "北京"};
//        String[] questionArr = {"求职", "厨师", "两千", "本科", "枣庄"};
        String[] questionArr = {"求职", "水上讲解员", "两千", "本科", "枣庄"};
        mSimulateAskBtn.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                sendMessage(Constants.SendMessageType.TYPE_ASK, questionArr[questionIndex]);
                questionIndex++;
                if (questionIndex == questionArr.length) {
                    questionIndex = 0;
                }
            }
        });

        mResetProcessBtn.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                sendMessage(Constants.SendMessageType.TYPE_END, "");
            }
        });
        mDestoryBtn.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View view) {
//                onBackPressed();
//                finish();
                if (app.isDebugMode) {
                    showDialog();
                } else {
                    finish();
                }
            }
        });
        mPauseResumeBtn = findViewById(R.id.pause_resume_talk_btn);
        mPauseResumeBtn.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                Log.e("potter", "mPauseResumeBtn:" + isForeground);
                if (isForeground) {
                    pauseTalk();
                    mPauseResumeBtn.setText("恢复对话");
                } else {
                    resumeTalk();
                    mPauseResumeBtn.setText("暂停会话");
                }
            }
        });
    }

    private void pauseTalk() {
        stopTTs();
        stopRecord();
        isForeground = false;
    }

    private void resumeTalk() {
        isForeground = true;
        wakeUp();
        startRecord();
    }

    private void updateStepUI(int step) {
        int focus = Color.parseColor("#0386F2");
        int non_focus = Color.parseColor("#000000");
        switch (step) {
            case 1:
                step1.setTextColor(focus);
                step2.setTextColor(non_focus);
                step3.setTextColor(non_focus);
                break;
            case 2:
                step1.setTextColor(non_focus);
                step2.setTextColor(focus);
                step3.setTextColor(non_focus);
                break;
            case 3:
                step1.setTextColor(non_focus);
                step2.setTextColor(non_focus);
                step3.setTextColor(focus);
                break;
            default:
                step1.setTextColor(focus);
                step2.setTextColor(non_focus);
                step3.setTextColor(non_focus);
                break;
        }
    }

    private void showDialog() {
        // 创建对话框构建器
        AlertDialog.Builder builder = new AlertDialog.Builder(TalkActivity.this);
//        builder.setTitle("确认退出");
//                .setPositiveButton("确定", new DialogInterface.OnClickListener() {
//                    @Override
//                    public void onClick(DialogInterface dialog, int which) {
//                        finish(); // 点击确定后关闭页面
//                    }
//                })
//                .setNegativeButton("取消", new DialogInterface.OnClickListener() {
//                    @Override
//                    public void onClick(DialogInterface dialog, int which) {
//                        dialog.dismiss(); // 点击取消关闭对话框
//                    }
//                });
        View dialogView = LayoutInflater.from(this).inflate(R.layout.dialog_container2, null);
        builder.setView(dialogView);
        remindTv = dialogView.findViewById(R.id.remind_tv);
        qrCodeImg = (ImageView) (dialogView.findViewById(R.id.qrcode_img));
        qrCodePreview = (DecoratedBarcodeView) dialogView.findViewById(R.id.qrcode_preview);
        phoneInputContainer = dialogView.findViewById(R.id.phoneInputContainer);
        closeDialogBtn = dialogView.findViewById(R.id.close_btn);
        submitBtn = dialogView.findViewById(R.id.info_submit_btn);
        phoneInput = dialogView.findViewById(R.id.etPhone);
        step1 = dialogView.findViewById(R.id.step_scan_social_code);
        step2 = dialogView.findViewById(R.id.step_show_qrcode);
        step3 = dialogView.findViewById(R.id.step_phone_input);
        updateStepUI(1);
        showPreview();
        capture = new CustomCaptureManager(this, qrCodePreview, this);
        Intent intent = getIntent();
        capture.initializeFromIntent(intent, null);
        capture.decode();
        capture.onResume();
        // 创建并配置对话框
        AlertDialog dialog = builder.create();
        dialog.setCanceledOnTouchOutside(false); // 点击外部不可关闭
//        dialog.setCancelable(false); // 禁用返回键关闭
        dialog.show();
        pauseTalk();
        dialog.setOnDismissListener(new DialogInterface.OnDismissListener() {
            @Override
            public void onDismiss(DialogInterface dialogInterface) {
                if (periodicRequestTask != null) {
                    periodicRequestTask.stopPeriodic();
                }
                resumeTalk();
            }
        });
        closeDialogBtn.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View view) {
                dialog.dismiss();
            }
        });
        submitBtn.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View view) {
                String phone = phoneInput.getText().toString();
                if (phone.length() < 11) {
                    toast("手机号不满11位，请检查");
                    return;
                }
                dialog.dismiss();
                submitInfo.put("phone", phoneInput.getText().toString());
                SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss", Locale.getDefault());
                Log.e("potter sdf submitTime", sdf.format(new Date()));
//                submitInfo.put("submitTime", sdf.format(new Date()));
                submitInfo.put("submitTime", String.valueOf(System.currentTimeMillis()));
                Log.e("potter submitTime", String.valueOf(System.currentTimeMillis()));
                handleSubmit();
            }
        });
    }

    private void handleSubmit() {
        //请求，把数据给到后端
        HttpClient client = HttpClient.getInstance();
        client.setBaseUrl("http://120.220.83.9:8333/agent/chat/");
        EmploymentInfo body = new EmploymentInfo();
        body.setCompanyName(submitInfo.get("company"));
        body.setJobTitle(submitInfo.get("title"));
        body.setName(submitInfo.get("name"));
        body.setIdCardNumber(submitInfo.get("idCard"));
        body.setPhoneNumber(submitInfo.get("phone"));
        if (submitInfo.get("title") == null || submitInfo.get("title").equals("")) {
            handler.post(new Runnable() {
                @Override
                public void run() {
                    startTTs(job_posted);
                }
            });
            toast(job_posted);
        } else {
            handler.post(new Runnable() {
                @Override
                public void run() {
                    startTTs(job_deliverd);
                }
            });
            toast(job_deliverd);
        }
        client.post("saveResume", body, SBResponseBean.class, new HttpClient.HttpCallback<SBResponseBean>() {
            @Override
            public void onSuccess(SBResponseBean response) {

            }

            @Override
            public void onFailure(Throwable throwable) {
                if (throwable instanceof HttpClient.AuthException) {
                    // 处理认证错误
                } else if (throwable instanceof HttpClient.ApiException) {
                    // 处理业务错误
                }
            }
        });
    }

    private void showPreview() {
        handler.post(new Runnable() {
            @Override
            public void run() {
                String fullText = "请将 社保二维码 放置于摄像头前";
                SpannableString spannableString = new SpannableString(fullText);
                String keyword = "社保二维码";
                int start = fullText.indexOf(keyword); // 起始位置
                int end = start + keyword.length();   // 结束位置
                int color = Color.parseColor("#FF0386F2"); // 如果不需要透明度直接用 #0386F2
                spannableString.setSpan(
                        new ForegroundColorSpan(color),
                        start,
                        end,
                        Spannable.SPAN_EXCLUSIVE_EXCLUSIVE
                );
                remindTv.setText(spannableString);
                qrCodePreview.setVisibility(View.VISIBLE);
                qrCodeImg.setVisibility(View.GONE);
                phoneInputContainer.setVisibility(View.GONE);
            }
        });
    }

    private void showQrCode() {
        handler.post(new Runnable() {
            @Override
            public void run() {
                remindTv.setText("请用微信二维码扫描完成人证核验");
                qrCodePreview.setVisibility(View.GONE);
                qrCodeImg.setVisibility(View.VISIBLE);
                phoneInputContainer.setVisibility(View.GONE);
            }
        });
    }

    private void showPhoneInput() {
        handler.post(new Runnable() {
            @Override
            public void run() {
                remindTv.setText("核验成功，请输入您的手机号");
                qrCodePreview.setVisibility(View.GONE);
                qrCodeImg.setVisibility(View.GONE);
                phoneInputContainer.setVisibility(View.VISIBLE);
            }
        });
    }

    private Toast toast;

    private void toast(String content) {
        handler.post(new Runnable() {
            @Override
            public void run() {
                if (toast == null) {
                    toast = Toast.makeText(TalkActivity.this, content, Toast.LENGTH_LONG);
                    toast.setGravity(Gravity.CENTER, 0, 0);
                } else {
                    toast.setText(content);
                }
                toast.show();
            }
        });
    }

    ;

    @Override
    public void onBarcodeResult(BarcodeResult result) {
        //扫描手机二维码获取的社保信息：9200开头的，(失效很快，可以用pc登录微信，开社保小程序扫描测试)
        String SSN = result.getText();
        Log.e("potter", "onBarcodeResult:" + SSN);
        if (!SSN.startsWith("9200")) {
            toast("识别到的社保码格式不正确，请重新扫码");
            capture.decode();
            capture.onResume();
            return;
        }
        capture.onPause();
        if (SSN != null && !SSN.isEmpty()) {
            submitInfo.put("ssn", SSN);
            getNameAndId(SSN);
        }
    }

    //根据ssn获取姓名和身份证号
    private void getNameAndId(String ssn) {
        HttpClient client = HttpClient.getInstance();
        client.setBaseUrl("http://120.220.83.9:8333/agent/chat/");
        SBRequestBean body = new SBRequestBean(ssn, "bjSFvpDyBKsldVDYJibe");
        client.post("getQRcode", body, SBResponseBean.class, new HttpClient.HttpCallback<SBResponseBean>() {
            @Override
            public void onSuccess(SBResponseBean response) {
                String name = response.getName();
                String idCard = response.getIdNumber();
                submitInfo.put("name", name);
                submitInfo.put("idCard", idCard);
                getQrCodeImageBaseNameAndId(name, idCard);
            }

            @Override
            public void onFailure(Throwable throwable) {
                if (throwable instanceof HttpClient.AuthException) {
                    // 处理认证错误
                } else if (throwable instanceof HttpClient.ApiException) {
                    // 处理业务错误
                    aaa++;
//                    toast("请刷新社保码后重试" + aaa);
                    toast("请刷新社保码后重试");
                    handler.postDelayed(new Runnable() {
                        @Override
                        public void run() {
                            capture.decode();
                            capture.onResume();
                        }
                    }, 100);
                }
            }
        });
    }

    public static final String WX_APP_ID = "wx21352c636fe1ca9c";//wx710ac067e316d503

    private int aaa = 0;

    //根据姓名和身份证生成二维码，手机微信扫描改二维码进行人脸校验
    private void getQrCodeImageBaseNameAndId(String name, String idCard) {
        HttpClient client = HttpClient.getInstance();
        String ROBOT_PERSON_API = "https://robotapi.zzrs.loginby.me/v1/";
        client.setBaseUrl(ROBOT_PERSON_API);
        PersonCheckQRCodeRequestBean body = new PersonCheckQRCodeRequestBean(
                "robot",
                "getqrcode",
                WX_APP_ID,
                "1",
                name,
                idCard,
                "release",
                450,
                false);
        client.post("", body, PersonCheckQRCodeResponseBean.class, new HttpClient.HttpCallback<PersonCheckQRCodeResponseBean>() {
            @Override
            public void onSuccess(PersonCheckQRCodeResponseBean response) {
                // 处理成功结果
                String qrBuffer = response.getData().getQr_buffer();
                Log.e("potter", "qrBuffer:" + qrBuffer);
                String reqid = response.getData().getReqid();
                Log.e("potter", "reqid:" + reqid);
                new ImageDownloader(TalkActivity.this, qrCodeImg)
                        .execute(qrBuffer);
                updateStepUI(2);
                showQrCode();
                pollingFaceVerifyResult(reqid);
            }

            @Override
            public void onFailure(Throwable throwable) {
                if (throwable instanceof HttpClient.AuthException) {
                    // 处理认证错误
                } else if (throwable instanceof HttpClient.ApiException) {
                    // 处理业务错误
                    aaa++;
                    toast("刷新社保码后重试" + aaa);
                    handler.postDelayed(new Runnable() {
                        @Override
                        public void run() {
                            capture.decode();
                            capture.onResume();
                        }
                    }, 100);
                }
            }
        });
    }

    private void pollingFaceVerifyResult(String reqid) {
        periodicRequestTask = new PeriodicRequestTask(new PeriodicRequestTask.OnPeriodicRequestStopListener() {
            @Override
            public void onPeriodicRequestStop(boolean isSuccess) {
//                toast(isSuccess ? "成功" : "失败");
                updateStepUI(3);
                showPhoneInput();
            }
        });
        periodicRequestTask.startPeriodicCheckQRCodeRequests(reqid);
    }

    @Override
    protected void onDestroy() {
        super.onDestroy();
        stopTTs();
        unbindService();
        handler.removeCallbacksAndMessages(null); // 防止内存泄漏
        unbindWebSocketService();
        if (periodicRequestTask != null) {
            periodicRequestTask.stopPeriodic();
        }
        EventBus.getDefault().unregister(this);
    }

    @Subscribe(threadMode = ThreadMode.MAIN)
    public void onMessageEvent(MessageEvent event) {
        // 在主线程处理事件，可更新 UI
        if (event.getMessage() == MessageEvent.POST_JOB) {
            submitInfo.put("title", "");
            submitInfo.put("company", "");
            showDialog();
        } else if (event.getMessage() == MessageEvent.DELIVER_RESUME) {
            Map<String, String> map = (Map<String, String>) event.getObj();
            String title = map.get("title");
            String company = map.get("company");
            Log.e("potter", "onMessageEvent title：" + title + "    company:" + company);
            submitInfo.put("title", title);
            submitInfo.put("company", company);
            showDialog();
        } else if (event.getMessage() == MessageEvent.REMOTE_INTERVIEW) {
            String meetingId = (String) event.getObj();
            Log.e("potter", "onMessageEvent meetingId：" + meetingId);
            jumpTxMeeting(meetingId);
        }
    }

    private void jumpTxMeeting(String id) {
        String meetingId = "304-220-918";
        meetingId = "304220918";//会议号要移除-
        Intent intent = new Intent(Intent.ACTION_VIEW);
        String schemeUrl = "wemeet://page/inmeeting?meeting_code=" + id;
        intent.setData(Uri.parse(schemeUrl));
        intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
        try {
            startActivity(intent);
        } catch (ActivityNotFoundException e) {
        }
    }

    @Override
    protected void onStop() {
        super.onStop();
    }

    @Override
    protected void onPause() {
        super.onPause();
        isForeground = false;
    }

    @Override
    protected void onResume() {
        super.onResume();
        isForeground = true;
    }

    // 更新时间显示
    private void updateTime() {
        Date now = new Date();
        tvTime.setText(timeFormat.format(now));
        tvDate.setText(dateFormat.format(now));
    }

    private void setTalkingState(int state) {
        mTalkingState = state; // 更新当前状态
        switch (state) {
            case IDLE:
                mTalkingStateText.setText("请说话");
                mWaveAnim.setVisibility(View.INVISIBLE);
                break;
            case MEN_TALKING:
                mTalkingStateText.setText("语音接收中...");
                mWaveAnim.setVisibility(View.VISIBLE);
//                mWaveAnim.setProgress(0f);    // 重置到起点
//                mWaveAnim.playAnimation();    // 重新播放
                break;
            case ROBOT_THINKING:
                mTalkingStateText.setText("大模型思考中...");
                mWaveAnim.setVisibility(View.VISIBLE);
//                mWaveAnim.setProgress(0f);    // 重置到起点
//                mWaveAnim.playAnimation();    // 重新播放
                break;
            case ROBOT_ANSWERING:
                mTalkingStateText.setText("机器人回答中...");
                mWaveAnim.setVisibility(View.VISIBLE);
//                mWaveAnim.setProgress(0f);    // 重置到起点
//                mWaveAnim.playAnimation();    // 重新播放
                break;
            default:
        }
    }

    // 启动定时更新
    private void startRealtimeUpdates() {
        handler.postDelayed(new Runnable() {
            @Override
            public void run() {
                updateTime();
                handler.postDelayed(this, 1000); // 每1秒更新一次
            }
        }, 1000);
    }

    private void bindService() {
        myServiceConnection = new MyServiceConnection();
        serviceCallBack = new ServiceCallBack();
        Intent intent = new Intent();
        intent.setComponent(new ComponentName("com.aobo.robot.ai3",
                "com.aobo.aibot.aidl.MyService"));
        startService(intent);
        bindService(intent, myServiceConnection, BIND_AUTO_CREATE);
    }

    private void unbindService() {
        if (myServiceConnection != null) {
            try {
                if (iMyAidlInterface != null) {
                    iMyAidlInterface.unregisterListener(serviceCallBack);
                }
            } catch (Exception e) {
                e.printStackTrace();
            }
            unbindService(myServiceConnection);
        }
    }

    private String answerStr = "";

    @Override
    public void onMessageStart(String conversationId) {
        Log.e("TalkActivity", "onMessageStart");
        mConversationId = conversationId;
        ChatMessage botMessage = ChatMessage.createBotTextMessage("");
        adapter.messages.add(botMessage);
        int position = adapter.messages.size() - 1;
        adapter.notifyItemInserted(position);
        mStopOutputBtn.setVisibility(View.VISIBLE);
    }

    @Override
    public void onMessageTypeChanged(String type) {
        Log.e("onMessageTypeChanged", type);
        runOnUiThread(new Runnable() {
            @Override
            public void run() {
                String preStr = "当前流程 ";
                String typeStr = "";
                switch (type) {
                    case "其他问题":
                        typeStr = "自然问答";
                        break;
                    case "与求职发布相关的问题":
                        typeStr = "求职问答";
                        break;
                    case "与政策问答相关的问题":
                        typeStr = "政策问答";
                        break;
                    default:
                        break;
                }
                String sourceText = preStr + typeStr;
                SpannableString spannableString = new SpannableString(sourceText);
                spannableString.setSpan(
                        new ForegroundColorSpan(Color.WHITE),
                        0,  // 起始位置
                        4,  // 结束位置（不包含）
                        Spannable.SPAN_EXCLUSIVE_EXCLUSIVE
                );
                spannableString.setSpan(
                        new ForegroundColorSpan(Color.parseColor("#FFEFAF")),
                        4,  // 起始位置
                        sourceText.length(),  // 结束位置
                        Spannable.SPAN_EXCLUSIVE_EXCLUSIVE
                );
                tvType.setText(spannableString);
            }
        });
    }

    @Override
    public void onMessageReceived(Object socketEntity) {
        if (socketEntity == null) return;
        if (socketEntity instanceof SocketMessageEntity) {
            SocketMessageEntity socketMessageEntity = (SocketMessageEntity) socketEntity;
            Log.e("TalkActivity onMessageReceived SocketMessageEntity", socketMessageEntity.getAnswer());
            answerStr = answerStr + socketMessageEntity.getAnswer();
            if (socketMessageEntity.getConversation_id() != null) {
                mConversationId = socketMessageEntity.getConversation_id();
            }
            if (socketMessageEntity.getTask_id() != null) {
                mTaskId = socketMessageEntity.getTask_id();
            }
            onReceiveWebsocketMsg(false, answerStr, socketMessageEntity.getAnswer());
        } else if (socketEntity instanceof SocketMessageEndEntity) {
            SocketMessageEndEntity socketMessageEndEntity = (SocketMessageEndEntity) socketEntity;
            Log.e("TalkActivity onMessageReceived SocketMessageEntity", ((SocketMessageEndEntity) socketEntity).getEvent());
            onReceiveWebsocketMsg(true, answerStr, "");
        } else if (socketEntity instanceof String) {
            Log.e("TalkActivity onMessageReceived", "message_end parse failed");
            answerStr = answerStr + (String)socketEntity;
            onReceiveWebsocketMsg(true, answerStr, (String)socketEntity);
        }
//        String robotResponse = str;
//        setTalkingState(ROBOT_ANSWERING);
//        ChatMessage botMessage = ChatMessage.createBotTextMessage(robotResponse);
//        adapter.messages.add(botMessage);
//        int position = adapter.messages.size() - 1;
//        adapter.notifyItemInserted(position);
//        adapter.updateMessage(position, String.valueOf(robotResponse));
//        ((LinearLayoutManager) recyclerView.getLayoutManager())
//                .scrollToPosition(position);
//        startTTs(str);
    }

    @Override
    public void onCommandReceived(String answer) {

    }

    @Override
    public void onJobListMessage(String introMsg, List<SocketJobListEntity> jobList) {
        answerStr = answerStr + introMsg;
        if (jobList != null) {
            showJobList(jobList);
        }
        onReceiveWebsocketMsg(false, answerStr, introMsg);
    }

    private void showJobList(List<SocketJobListEntity> jobList) {
        List<Job> jobs = new ArrayList<Job>();
        for (int i = 0; i < jobList.size(); i++) {
            SocketJobListEntity jobEntity = jobList.get(i);
            Log.e("potterAAA location", jobEntity.getJob_location());
            Log.e("potterAAA isscreen", jobEntity.getIs_screen() ? "true" : "false");
            if (jobEntity.getIs_screen()) {
                Log.e("potterAAA getMeeting_id", jobEntity.getMeeting_id());
                Log.e("potterAAA getMeeting_url", jobEntity.getMeeting_url());
            }

            jobs.add(
                    new Job(
                            jobEntity.getJob_name(),
                            jobEntity.getCompany(),
                            jobEntity.getJob_location(),
                            "",
                            false,
                            jobEntity.getIs_screen(),
                            true,
                            jobEntity.getIs_screen() ? jobEntity.getMeeting_id() : "",
                            jobEntity.getIs_screen() ? jobEntity.getMeeting_url() : ""
                    )
            );
        }
//        List<Job> jobs = new ArrayList<Job>() {{
//            add(new Job(
//                    "Java开发工程师",
//                    "字节跳动",
//                    "北京",
//                    "25-40K·16薪",
//                    true,
//                    true,
//                    true
//            ));
//
//            add(new Job(
//                    "Android开发专家",
//                    "腾讯科技",
//                    "深圳",
//                    "30-50K·14薪",
//                    true,
//                    false,
//                    true
//            ));
//
//            add(new Job(
//                    "大数据平台开发",
//                    "阿里巴巴集团",
//                    "杭州",
//                    "20-35K·股票期权",
//                    false,
//                    true,
//                    true
//            ));
//
//            add(new Job(
//                    "移动端架构师",
//                    "美团平台",
//                    "上海",
//                    "40-60K·技术分红"
//            ));
//
//            add(new Job(
//                    "跨平台开发工程师",
//                    "快手科技",
//                    "广州",
//                    "18-30K·弹性工作"
//            ));
//        }};
        ChatMessage botMessage = ChatMessage.createBotJobMessage("", jobs);
        adapter.messages.remove(adapter.messages.size() - 1);
        adapter.messages.add(botMessage);
        int position = adapter.messages.size() - 1;
        adapter.notifyItemInserted(position);
    }


    class MyServiceConnection implements ServiceConnection {

        @Override
        public void onServiceConnected(ComponentName componentName, IBinder iBinder) {
            iMyAidlInterface = IMyAidlInterface.Stub.asInterface(iBinder);

            handler.post(new Runnable() {
                @Override
                public void run() {
                    //注册回调
                    if (iMyAidlInterface != null) {
                        try {
                            iMyAidlInterface.registerListener(serviceCallBack);
                        } catch (Exception e) {
                            e.printStackTrace();
                        }
                    }
                }
            });
        }

        @Override
        public void onServiceDisconnected(ComponentName componentName) {

        }
    }

    /**
     * service回调client的类
     * tag
     * 为1是返回识别音量
     * 为2是返回识别的内容
     * 为3是合成消息
     * 为4是唤醒消息
     * 为front_ultrasound 是前超声波消息
     * 为back_ultrasound 为后超声波消息
     * 为ultrasound_distance 为超声波距离
     */
    class ServiceCallBack extends IMyAidlCallBackInterface.Stub {
        String lastTimeMsg = "N/A";

        @Override
        public void callback(final String tag, final String message) throws RemoteException {
            runOnUiThread(new Runnable() {
                @Override
                public void run() {
                    if (!tag.equals("1") && logText != null) {
                        logText.append("tag = " + tag + "  message=" + message + "\n");
                        logContainer.fullScroll(View.FOCUS_DOWN);
                    }
                    if (!isForeground) {
                        return;
                    }
                    //唤醒时说欢迎(人脸识别后迎宾)
                    if (tag.equals("4")) {
                        if (message.startsWith("wake up")) {
                            if (app.useDeviceWakeup) {

                            } else {
                                startTTs(welComeStr);
                            }
                        }
                    }
                    //语音播报结束或中断-->开启录制新的一轮人的说话，语音识别
                    if (tag.equals("3") && (message.equals("ttsover") || message.equals("ttsstop"))) {
                        mStopOutputBtn.setVisibility(View.INVISIBLE);
                        //求职发布和投递简历最后一步 播报语音结束后关闭当前页
                        if (lastTTs.equals(job_posted) || lastTTs.equals(job_deliverd)) {
                            finish();
                        } else {
                            startRecord();
                        }
                    }
                    //语音识别过程，startRecord,callback第一次(tag:2,message:"startrecord")-->
                    // 人说话-->callback第二次(tag:2,message:msg)-->
                    // 底层自己stoprecord-->callback第三次((tag:2,message:"stoprecord")
                    if (tag.equals("2")) {
                        if (message.equals("stoprecord") && lastTimeMsg.equals("")) {
                            //此时的情景是人没有说话，我们继续startRecord
                            noVoiceInputTimes++;
                            if (noVoiceInputTimes >= MAX_SILENT_TIME) {
                                finish();
                            }
                            startRecord();
                            return;
                        }
                        if (message.equals("stoprecord") || message.equals("startrecord")) {
                            return;
                        }
                        lastTimeMsg = message;
                        if (message.equals("")) {
                            return;
                        } else {
                            noVoiceInputTimes = 0;
                        }
                        String pingyin = convertToPinyin(message);
                        for (int i = 0; i < targetPinyins.size(); i++) {
                            String targetPinyin = targetPinyins.get(i);
                            if (pingyin.contains(targetPinyin)) {
//                                unbindService();
                                finish();
                                return;
                            }
                        }
                        setTalkingState(ROBOT_THINKING);
                        String menInput = message;
                        // 添加用户消息
                        ChatMessage userMessage = ChatMessage.createUserMessage(menInput);
                        adapter.messages.add(userMessage);
                        int position = adapter.messages.size() - 1;
                        adapter.notifyItemInserted(position);
                        adapter.updateMessage(position, String.valueOf(userMessage.getContent()));
                        ((LinearLayoutManager) recyclerView.getLayoutManager())
                                .scrollToPosition(position);
                        sendMessage(Constants.SendMessageType.TYPE_ASK, menInput);
                        answerStr = "";
                    }
                }
            });
        }
    }

    private String mConversationId = null;
    private String mTaskId = null;

    private boolean showAnswer = false;

    public void sendMessage(String sendMessageType, String message) {
        if (mBound && mServiceBinder != null) {
            socketService socketServiceInstance = mServiceBinder.getService();
            uuid = socketServiceInstance.getUUID();
            if (socketServiceInstance != null) {
                SendMessageEntity sendMessageEntity = new SendMessageEntity();
                if (Constants.SendMessageType.TYPE_ASK.equals(sendMessageType)) {
                    sendMessageEntity.setDirective(Constants.SendMessageType.TYPE_ASK);//stop 结束流式返回 end 结束流程 answer 提问
//                sendMessageEntity.setConversationId("setConversationId");//每次重新打开聊天界面是一个新id，从服务端获取，第二次开始传
                    if (mConversationId != null && !mConversationId.isEmpty()) {
                        sendMessageEntity.setConversationId(mConversationId);
                    }
                    sendMessageEntity.setQuery(message);//用户问题
//                sendMessageEntity.setTaskId("setTaskId");//具体某一条问题的id
                    if (mTaskId != null && !mTaskId.isEmpty()) {
                        sendMessageEntity.setTaskId(mTaskId);
                    }
                    sendMessageEntity.setSessionId(uuid);//每次进入聊天界面重新生成sessionid,使用uuid
                    Log.e("TalkActivity uuid ask", uuid);
                    sendMessageEntity.setInputs(new HashMap<>());
                    String jsonString = new Gson().toJson(sendMessageEntity);
                    socketServiceInstance.sendMessage(jsonString);
                    showAnswer = true;
                } else if (Constants.SendMessageType.TYPE_STOP.equals(sendMessageType)) {
                    Log.e("TalkActivity TYPE_STOP", uuid);
                    showAnswer = false;
                    sendMessageEntity.setDirective(Constants.SendMessageType.TYPE_STOP);
                    if (mConversationId != null && !mConversationId.isEmpty()) {
                        sendMessageEntity.setConversationId(mConversationId);
                    }
                    sendMessageEntity.setQuery(message);//用户问题
                    if (mTaskId != null && !mTaskId.isEmpty()) {
                        sendMessageEntity.setTaskId(mTaskId);
                    }
                    sendMessageEntity.setSessionId(uuid);//每次进入聊天界面重新生成sessionid,使用uuid
                    sendMessageEntity.setInputs(new HashMap<>());
//                    String jsonString = new Gson().toJson(sendMessageEntity);
//                    socketServiceInstance.sendMessage(jsonString);
                    sendMessageStop(sendMessageEntity);
//                    mTaskId = null;

                } else if (Constants.SendMessageType.TYPE_END.equals(sendMessageType)) {
                    sendMessageEntity.setDirective(Constants.SendMessageType.TYPE_END);
                    if (mConversationId != null && !mConversationId.isEmpty()) {
                        sendMessageEntity.setConversationId(mConversationId);
                    }
                    sendMessageEntity.setQuery(message);//用户问题
                    if (mTaskId != null && !mTaskId.isEmpty()) {
                        sendMessageEntity.setTaskId(mTaskId);
                    }
                    sendMessageEntity.setSessionId(uuid);//每次进入聊天界面重新生成sessionid,使用uuid
                    sendMessageEntity.setInputs(new HashMap<>());
//                    String jsonString = new Gson().toJson(sendMessageEntity);
//                    socketServiceInstance.sendMessage(jsonString);
                    sendMessageEnd(sendMessageEntity);
//                    mTaskId = null;
//                    mConversationId = null;
                }
            }
        }
    }

    private OkHttpClient client = new OkHttpClient();
    private Gson gson = new Gson();

    private void sendMessageEnd(SendMessageEntity sendMessageEntity) {
        Log.e("TalkActivity uuid end", sendMessageEntity.getSessionId());
        String url = "http://" + HOST + "/agent/chat/end";
        String json = gson.toJson(sendMessageEntity);
        RequestBody body = RequestBody.create(MediaType.parse("application/json"), json);
        Request request = new Request.Builder()
                .url(url)
                .post(body)
                .build();

        client.newCall(request).enqueue(new Callback() {
            @Override
            public void onFailure(Call call, IOException e) {
                e.printStackTrace();
            }

            @Override
            public void onResponse(Call call, Response response) throws IOException {
                Log.e("TalkActivity sendMessageEnd onResponse", response.toString());
                if (response.isSuccessful()) {
                    Log.e("", "");
                    handler.post(new Runnable() {
                        @Override
                        public void run() {
                            tvType.setText("大模型智能对话");
                        }
                    });
                } else {
                    // 处理错误情况
                }
            }
        });
    }

    private void sendMessageStop(SendMessageEntity sendMessageEntity) {
        Log.e("TalkActivity uuid stop", sendMessageEntity.getSessionId());
        String url = "http://" + HOST + "/agent/chat/stop";
        String json = gson.toJson(sendMessageEntity);
        RequestBody body = RequestBody.create(MediaType.parse("application/json"), json);
        Request request = new Request.Builder()
                .url(url)
                .post(body)
                .build();

        client.newCall(request).enqueue(new Callback() {
            @Override
            public void onFailure(Call call, IOException e) {
                e.printStackTrace();
            }

            @Override
            public void onResponse(Call call, Response response) throws IOException {
                Log.e("TalkActivity sendMessageStop onResponse", response.toString());
                Log.e("TalkActivity sendMessageStop isSuccessful", String.valueOf(response.isSuccessful()));
                if (response.isSuccessful()) {
                    stopTTs();
                } else {
                    // 处理错误情况
                }
            }
        });
    }

    //websocket onMessage，用接口实现，或者广播转发都可以
    private void onReceiveWebsocketMsg(boolean end, String str, String appendStr) {
        String robotResponse = str;
        setTalkingState(ROBOT_ANSWERING);
        int position = adapter.messages.size() - 1;
        adapter.updateMessage(position, appendStr);
        ((LinearLayoutManager) recyclerView.getLayoutManager())
                .scrollToPosition(position);
        if (end) {
            String str2 = str.replace("*", "");
            startTTs(str2);
        }
    }

    private void startTTs(String str) {
//        语音合成，机器人说话
//        startTTs
        lastTTs = str;
        if (!isForeground) {
            return;
        }
        if (iMyAidlInterface != null) {
            try {
                iMyAidlInterface.sendMessage("starttts", str);
            } catch (RemoteException e) {
                e.printStackTrace();
            }
        }
    }

    private void stopTTs() {
//        语音合成中断
//        stopTTs
        if (iMyAidlInterface != null) {
            try {
                iMyAidlInterface.sendMessage("stoptts", "");
            } catch (RemoteException e) {
                e.printStackTrace();
            }
        }
    }

    private String convertToPinyin(String chinese) {
        Transliterator transliterator = null;
        Transliterator transliterator2 = null;
        if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.Q) {
            //转的是带音调的
            transliterator = Transliterator.getInstance("Han-Latin");
            //干掉音调
            transliterator2 = Transliterator.getInstance("Latin-ASCII");
            String str = transliterator.transliterate(chinese);
            return transliterator2.transliterate(str).replaceAll("\\s+", "");
        }
        return "";
    }

}